/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package proyecto2;

import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.Observable;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

/**
 *
 * @author Damian
 */
public class Cliente extends Observable {

    private ObjectOutputStream salida;
    private ObjectInputStream entrada;
    private String mensaje = "";
    private String servidorChat;
    private Socket cliente;
    String msg = "no llego";
    int puerto;
    String ip;
    Thread h;

    public Cliente(String host, int puerto) {


        servidorChat = host; // establecer el servidor al que se va a conectar este cliente
        this.puerto = puerto;
        Runnable hilo = new Runnable() {
            @Override
            public void run() {
                ejecutarCliente();
            }
        };
        h = new Thread(hilo);
        h.start();

    }

    // conectarse al servidor y procesar mensajes del servidor
    void ejecutarCliente() {
        // conectarse al servidor, obtener flujos, procesar la conexión
        try {
            conectarAServidor(); // Paso 1: crear un socket para realizar la conexión
            obtenerFlujos();      // Paso 2: obtener los flujos de entrada y salida
            procesarConexion(); // Paso 3: procesar la conexión
        } // el servidor cerró la conexión
        catch (EOFException excepcionEOF) {
            System.err.println("El cliente termino la conexión");
        } // procesar los problemas que pueden ocurrir al comunicarse con el servidor
        catch (IOException excepcionES) {
            excepcionES.printStackTrace();
        } finally {
            cerrarConexion(); // Paso 4: cerrar la conexión
        }

    } // fin del método ejecutarCliente

    // conectarse al servidor
    private void conectarAServidor() throws IOException {
        mostrarMensaje("Intentando realizar conexión\n");

        // crear Socket para realizar la conexión con el servidor
        cliente = new Socket(InetAddress.getByName(servidorChat), puerto);

        // mostrar la información de la conexión
        mostrarMensaje("Conectado a: "
                + cliente.getInetAddress().getHostName());
//        System.out.println("Conectado a: "
//                + cliente.getInetAddress().getHostName());
    }

    // obtener flujos para enviar y recibir datos
    private void obtenerFlujos() throws IOException {
        // establecer flujo de salida para los objetos
        salida = new ObjectOutputStream(cliente.getOutputStream());
        salida.flush(); // vacíar búfer de salida para enviar información de encabezado

        // establecer flujo de entrada para los objetos
        entrada = new ObjectInputStream(cliente.getInputStream());

        mostrarMensaje("\nSe recibieron los flujos de E/S\n");
    }

    // procesar la conexión con el servidor
    private void procesarConexion() throws IOException {
        // habilitar campoIntroducir para que el usuario del cliente pueda enviar mensajes
        do { // procesar mensajes enviados del servidor
            // leer mensaje y mostrarlo en pantalla
            try {
                mensaje = (String) entrada.readObject();
                msg = mensaje;
                mostrarMensaje("\n" + mensaje);
                System.out.println("asdff");
                this.setChanged();
                this.notifyObservers();
            } // atrapar los problemas que pueden ocurrir al leer del servidor
            catch (ClassNotFoundException excepcionClaseNoEncontrada) {
                mostrarMensaje("\nSe recibió un objeto de tipo desconocido");
            } catch (SocketException se) {
                System.out.println("Desconectado");
                JOptionPane.showMessageDialog(null, "Se perdio la conexion");
                System.exit(0);
                h.stop();
            }
        } while (!mensaje.equals("SERVIDOR>>> TERMINAR"));

    } // fin del método procesarConexion

    private void cerrarConexion() {
        mostrarMensaje("\nCerrando conexión");
        try {
            salida.close();
            entrada.close();
            cliente.close();
        } catch (IOException excepcionES) {
            excepcionES.printStackTrace();
        }
    }
    // enviar mensaje al servidor

    void enviarDatos(String mensaje) {
        // enviar objeto al servidor
        try {
            salida.writeObject(mensaje);
            salida.flush();
            mostrarMensaje("\nCLIENTE>>> " + mensaje);
        } // procesar los problemas que pueden ocurrir al enviar el objeto
        catch (IOException excepcionES) {
            // areaPantalla.append( "\nError al escribir el objeto" );
        }
    }

    // método utilitario que es llamado desde otros subprocesos para manipular a 
    // areaPantalla en el subproceso despachador de eventos
    private void mostrarMensaje(final String mensajeAMostrar) {
        // mostrar mensaje del subproceso de ejecución de la GUI
        SwingUtilities.invokeLater(
                new Runnable() {  // clase interna para asegurar que la GUI se actualice apropiadamente
            public void run() // actualiza areaPantalla
            {
//               areaPantalla.append( mensajeAMostrar );
//               areaPantalla.setCaretPosition( 
//                  areaPantalla.getText().length() );
                System.out.println(mensajeAMostrar);
            }
        } // fin de la clase interna
                ); // fin de la llamada a SwingUtilities.invokeLater
    }
}
